#include "PhidgetValueObject.h"
#include "PhidgetManager.h"
#include "PhidgetPropertyAlias.h"
#include <stdexcept>


//
// Retrieve the value of a property for this object.
//
JSBool PhidgetValueObject::getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
	PhidgetValueObject *pvo;
    jsval idvp;
    std::string property, value;
    int nValue;
    JSString *str;
    

    //
    // Get the root object that we need to work with.
    //
    pvo = (PhidgetValueObject *)JS_GetPrivate(cx, obj);

	//
	// Get the property name they wish to retrieve.
	//
	JS_BeginRequest(cx);
    JS_IdToValue(cx, id, &idvp);
    property = std::string(JS_EncodeString(cx, JS_ValueToString(cx, idvp)));
    JS_EndRequest(cx);

	//
	// Get the value of this property.
	//
    value = pvo->manager->GetPropertyValue(property);
    
    //
    // Convert the value string into a JS value.
    //
    JS_BeginRequest(cx);
    nValue = atoi(value.c_str());
    str = JS_NewStringCopyN(cx, value.c_str(), value.size());
    *vp = STRING_TO_JSVAL(str);
    JS_EndRequest(cx);

	return JS_TRUE;
}


//
// Set the value of an I/O property.
//
JSBool PhidgetValueObject::setProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
{
	PhidgetValueObject *pvo;
    jsval idvp;
    std::string property, value;
    

    //
    // Get the object that we need to work with.
    //
    pvo = (PhidgetValueObject *)JS_GetPrivate(cx, obj);
    
    //
    // Convert the JS property name and value into strings that we can work with.
    //
    JS_BeginRequest(cx);
    JS_IdToValue(cx, id, &idvp);
    property = std::string(JS_EncodeString(cx, JS_ValueToString(cx, idvp)));
    value = std::string(JS_EncodeString(cx, JS_ValueToString(cx, *vp)));
    JS_EndRequest(cx);

	//
	// Set the value of the property.
	//
	pvo->manager->SetPropertyValue(property, value);

	return JS_TRUE;
}


//
// Define the class information for the JS object.
//
static JSClass object_class = {
    "PhidgetValue", JSCLASS_HAS_PRIVATE,
    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    JSCLASS_NO_OPTIONAL_MEMBERS
};



//
// Create the new root PhidgetValue object.
//
PhidgetValueObject::PhidgetValueObject(PhidgetManager *pm, MonkeyRuntime *rt)
{
	//
	// Save the manager for later use.
	//
	manager = pm;
	
	//
	// We have to set these here because they are private members.
	//
	object_class.getProperty = PhidgetValueObject::getProperty;
	object_class.setProperty = PhidgetValueObject::setProperty;
}


//
// Register this object with the parent object.
//
void PhidgetValueObject::RegisterObject(MonkeyContext *ctx, JSObject *parent)
{
	MonkeyObject::RegisterObject(ctx, parent);

	JS_BeginRequest(Context()->jsContext());
	object = JS_DefineObject(Context()->jsContext(), parent, "value", &object_class, NULL, (JSPROP_READONLY | JSPROP_PERMANENT));
	JS_SetPrivate(Context()->jsContext(), object, this);
	JS_EndRequest(Context()->jsContext());
}




